<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>bpkg-repository-types(1) bpkg 0.17.0</title>

  <style type="text/css">
/* file      : common.css
 * license   : MIT; see accompanying LICENSE file
 */

html
{
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
  font-weight: normal;
  font-size: 18px;
  line-height: 1.4em;
  letter-spacing: 0.01em;

  color: #292929;
}

body {margin: 0;} /* There is non-0 default margin for body. */

/* See notes on what's going on here. */
body {min-width: 17em;}
@media only screen and (min-width: 360px)
{
  body {min-width: 19em;}
}

/*
 * Header (optional).
 */

#header-bar
{
  width: 100%;

  background: rgba(0, 0, 0, 0.04);
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);

  padding: .4em 0 .42em 0;
  margin: 0 0 1.4em 0;
}

#header
{
  /* Same as in #content. */
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;

  width: 100%;
  display: table;
  border: none;
  border-collapse: collapse;
}

#header-logo, #header-menu
{
  display: table-cell;
  border: none;
  padding: 0;
  vertical-align: middle;
}

#header-logo {text-align: left;}
#header-menu {text-align: right;}

/* These overlap with #header's margin because of border collapsing. */
#header-logo {padding-left: .4em;}
#header-menu {padding-right: .4em;}

#header-logo a
{
  color: #000;
  text-decoration: none;
  outline: none;
}
#header-logo a:visited {color: #000;}
#header-logo a:hover, #header-logo a:active {color: #000;}

#header-menu a
{
  font-size: 0.889em;
  line-height: 1.4em;
  text-align: right;
  margin-left: 1.2em;
  white-space: nowrap;
  letter-spacing: 0;
}

#header-menu a
{
  color: #000;
  outline: none;
}
#header-menu a:visited {color: #000;}
#header-menu a:hover, #header-menu a:active
{
  color: #3870c0;
  text-decoration: none;
}

/* Flexbox-based improvements though the above works reasonably well. */
#header-menu-body
{
  width: 100%;

  display: -webkit-inline-flex;
  display: inline-flex;

  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;

  -webkit-justify-content: flex-end;
  justify-content: flex-end;
}

/* Whether we want it (and at which point) depends on the size of the menu. */
/*
@media only screen and (max-width: 567px)
{
  #header-menu-body
  {
    -webkit-flex-direction: column;
    flex-direction: column;
  }
}
*/

/*
 * Content.
 */

#content
{
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em; /* Space between text and browser frame. */

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

/*
 * Footer (optional).
 */

#footer
{
  color: #767676;
  font-size: 0.7223em;
  line-height: 1.3em;
  margin: 2.2em 0 1em 0;
  text-align: center;
}

#footer a
{
  color: #767676;
  text-decoration: underline;
}
#footer a:visited {color: #767676;}
#footer a:hover, #footer a:active {color: #3870c0;}

/* Screen size indicator in the footer. The before/after content is in case
   we don't have any content in the footer. Margin is to actually see the
   border separate from the browser frame. */

/*
#footer:before {content: "\A0";}
#footer:after {content: "\A0";}

#footer
{
  border-left: 1px solid;
  border-right: 1px solid;
  margin-left: 1px;
  margin-right: 1px;
}

@media only screen and (max-width: 359px)
{
  #footer {border-color: red;}
}

@media only screen and (min-width: 360px) and (max-width: 567px)
{
  #footer {border-color: orange;}
}

@media only screen and (min-width: 568px) and (max-width: 1023px)
{
  #footer {border-color: blue;}
}

@media only screen and (min-width: 1024px)
{
  #footer {border-color: green;}
}
*/

/*
 * Common elements.
 */

p, li, dd {text-align: justify;}
.code {text-align: left;} /* Manually aligned. */
pre {text-align: left;}   /* If it is inside li/dd. */

/* Notes. */

.note
{
  color: #606060;
}

div.note
{
  margin: 2em 0 2em 0; /* The same top/bottom margings as pre box. */

  padding-left: 0.5em;
  border: 0.25em;
  border-left-style: solid;
  border-color: #808080;

  page-break-inside: avoid;
}

div.note :first-child {margin-top:    0;}
div.note :last-child  {margin-bottom: 0;}

span.note::before {content: "[Note: "}
span.note::after  {content: "]"}

/* Links. */
a
{
  color: #3870c0;
  /*color: #4078c0;*/
  text-decoration: none;
}

a:hover, a:active
{
/*color: #006fbf;*/
/*color: #0087e7;*/
  text-decoration: underline;
}

a:visited
{
/*color: #003388;*/
  color: #00409c;
}

/* Standard paragraph. */

p, pre {margin: 1em 0 1em 0;}

/* Standard lists. */
ul, ol, dl {margin: 1em 0 1em 0;}
ul li, ol li {margin: 0 0 .4em 0;}
ul li {list-style-type: circle;}
dl dt {margin: 0 0 0 0;}
dl dd {margin: 0 0 .6em 1.8em;}

code, pre
{
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 0.92em;
  letter-spacing: 0;
}

pre {white-space: pre-wrap;}
@media only screen and (max-width: 567px)
{
  pre {word-break: break-all;}
}

/* Use page rather than system font settings. */
input
{
  font-family: inherit;
  font-weight: inherit;
  font-size:   inherit;
  line-height: inherit;
}

/* file      : pre-box.css
 * license   : MIT; see accompanying LICENSE file
 */

/* Note: see also p-code-box.css. */

pre
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .8em .4em .8em .4em;
  margin: 2em -.4em 2em -.4em; /* Use margins of #content. */
}

/* file      : man.css
 * license   : MIT; see accompanying LICENSE file
 */

/* Bases:
 *
 * common.css
 * pre-box.css
 *
 */

#content
{
  max-width: 42.1em;
  padding-left: 1.5em; /* Reserve for the heading. */
}

h1
{
  font-weight: normal;
  font-size: 1.58em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -.88em;
}

/* Definition list for options. */
dl.options dt {margin: 1em 0 0 0;}
dl.options dd {margin: .1em 0 0 4.5em;}

/* Make lists inside option descriptions a tad smaller. */
dl.options dd ul, dl.options dd ol, dl.options dd dl
{
  font-size: 0.889em;
  line-height: 1.4em;
}

  </style>

</head>
<body>
<div id="content">

  <h1>NAME</h1>

  <p><b><code>bpkg-repository-types</code></b> &#8211; repository types, structure, and URLs</p>
  <h1>DESCRIPTION</h1>

  <p>This help topic describes the repository types recognized by
  <code><b>bpkg</b></code>, their structure, and the format of their URLs.
  Currently three types of repositories are supported: archive-based
  <code><b>pkg</b></code>, directory-based <code><b>dir</b></code>, and
  version control-based <code><b>git</b></code>.</p>

  <p>The repository location may specify the repository type as part of the
  URL scheme component in the <code><i>type</i><b>+</b><i>protocol</i></code>
  form. For example:</p>

  <pre>git+https://example.com/foo
dir+file:///tmp/repo</pre>

  <p>Note that the explicit specification is only needed when the correct type
  cannot be guessed from the URL. See <a
  href="bpkg-rep-add.xhtml"><code><b>bpkg-rep-add(1)</b></code></a> for
  details.</p>

  <h1>PKG REPOSITORIES</h1>

  <p>A <code><b>pkg</b></code> repository is <i>archive</i>-based. That is, it
  contains a collection of various packages/versions as archive files. For
  more information on the structure of <code><b>pkg</b></code> repositories
  refer to <a href="build2-package-manager-manual.xhtml">The
  <code><b>build2</b></code> Package Manager Manual</a>. The
  <code><b>pkg</b></code> repository location can be a local directory path or
  an <code><b>http(s)://</b></code> URL.</p>

  <h1>DIR REPOSITORIES</h1>

  <p>A <code><b>dir</b></code> repository is <i>directory</i>-based. That is,
  it contains a collection of various packages as directories but only a
  single version per package can be present in such a repository. The
  <code><b>dir</b></code> repository location can be a local directory path or
  a <code><b>file://</b></code> URL.</p>

  <p>A <code><b>dir</b></code> repository is expected to contain either the
  <code><b>manifest</b></code> or <code><b>packages.manifest</b></code> file
  in the root directory of the repository. If it only contains
  <code><b>manifest</b></code>, then it is assumed to be a simple,
  single-package repository with the <code><b>manifest</b></code> file being
  its package manifest. Otherwise, the <code><b>packages.manifest</b></code>
  file should list the locations of available packages as described in <a
  href="build2-package-manager-manual.xhtml#manifest-package-list-dir">Package
  List Manifest for <code><b>dir</b></code> Repositories</a>.</p>

  <p>A <code><b>dir</b></code> repository may also contain the
  <code><b>repositories.manifest</b></code> file in the root directory of the
  repository. This file can be used to describe the repository itself as well
  as specify its prerequisite and complement repositories. See <a
  href="build2-package-manager-manual.xhtml#manifest-repository-list">Repository
  List Manifest</a> for details on the format and semantics of this file.</p>

  <h1>GIT REPOSITORIES</h1>

  <p>A <code><b>git</b></code> repository is <i>version control</i>-based.
  That is, it normally contains multiple versions of the same package (but can
  also contain several, usually related, packages in the same repository).</p>

  <p>A <code><b>git</b></code> repository has the same structure and manifest
  files as the <code><b>dir</b></code> repository. See <a
  href="build2-package-manager-manual.xhtml#manifest-package-list-dir">Package
  List Manifest for <code><b>dir</b></code> Repositories</a> and <a
  href="build2-package-manager-manual.xhtml#manifest-repository-list">Repository
  List Manifest</a> for details on their format and semantics.</p>

  <p>Theoretically, a <code><b>git</b></code> repository may contain as many
  package versions as there are commits. Practically, however, we are normally
  only interested in a small subset of them while fetching and processing the
  necessary information for all of them could be prohibitively expensive.  As
  a result, by default, only advertised tags in the
  <code><b>refs/tags/v*</b></code> form where the part after
  <code><b>v</b></code> is also a valid <a
  href="../../build2/doc/build2-build-system-manual.xhtml#module-version">standard
  version</a> are considered to be sources of useful package versions. These
  commits normally correspond to released versions and are called the
  <i>default set</i>. Note that only the latest revision of each such version
  is considered.</p>

  <p>Instead of the default set, it is possible to provide a custom set of
  available versions by specifying one or more commit ids and/or references
  and/or reference patterns in the repository URL fragment (see
  <code><b>git-ls-remote(1)</b></code> for details on advertised references).
  For example:</p>

  <pre>https://example.com/foo.git#v1.2.3
https://example.com/foo.git#master
https://example.com/foo.git#af234f56
https://example.com/foo.git#tags/releases/*
https://example.com/foo.git#HEAD,tags/v1.*.*,heads/feature-*</pre>

  <p>Furthermore, it is possible to expand (or narrow down) the default set
  using the special <code><b>##</b></code> fragment notation. For example:</p>

  <pre>https://example.com/foo.git##HEAD     - default set plus HEAD
https://example.com/foo.git##heads/*  - default set plus branches
https://example.com/foo.git##-v1.*    - default set minus v1.*</pre>

  <p>A <code><b>git</b></code> repository URL fragment is a comma-separated
  list of reference filters in the following form:</p>

  <p class="code"><code>[<i>refname</i>][<b>@</b><i>commit</i>]</code></p>

  <p>Either <code><i>refname</i></code>, <code><i>commit</i></code>, or both
  must be specified. If both are specified then <code><i>refname</i></code> is
  only used to minimize the amount of data fetched and
  <code><i>commit</i></code> is expected to belong to its history. For
  example:</p>

  <pre>.../foo.git#master@48fba3625d65941bb85a39061bcf795d4949c778</pre>

  <p>The <code><i>refname</i></code> part can be an abbreviated commit id or
  an advertised reference or reference pattern under
  <code><b>refs/</b></code>. While <code><i>commit</i></code> must be the
  complete, 40-characters SHA1 that need not be advertised. For convenience, a
  40-characters filter that consists of only hexadecimal digits is assumed to
  be <code><i>commit</i></code> even if not prefixed with
  <code><b>@</b></code>. In an unlikely event this produces an incorrect
  result, the <code><b>@</b></code>-form with omitted
  <code><i>commit</i></code> can be used. For example:</p>

  <pre>.../foo.git#48fba3625d65941bb85a39061bcf795d4949c778   (commit id)
.../foo.git#deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@  (reference)</pre>

  <p>The <code><i>refname</i></code> part can use the <code><b>*</b></code>
  and <code><b>?</b></code> wildcard pattern characters with the standard
  semantics as well as the <code><b>**</b></code> character sequence which
  matches in subdirectories, recursively. For example:</p>

  <pre>.../foo.git#tags/v*    - tags/v1.2.3 but not tags/old/v0.1.0
.../foo.git#tags/v**   - tags/v1.2.3 and tags/old/v0.1.0</pre>

  <p>A relative <code><i>refname</i></code> is searched for in
  <code><b>refs/</b></code>, <code><b>refs/tags/</b></code>, and
  <code><b>refs/heads/</b></code> as well as among symbolic references like
  <code><b>HEAD</b></code>. To anchor it to <code><b>refs/</b></code> make it
  absolute, for example:</p>

  <pre>.../foo.git#tags/v*   - refs/tags/v1.2.3 but also refs/heads/tags/voo
.../foo.git#/tags/v*  - refs/tags/v1.2.3 only</pre>

  <p>While a <code><i>refname</i></code> pattern is allowed not match any
  references, a non-pattern that doesn't resolve to a reference is
  invalid.</p>

  <p>If a <code><i>refname</i></code> starts with minus
  (<code><b>-</b></code>) then it is treated as an exclusion filter &#8211;
  any references that it matches are excluded from the set included by the
  preceding filters (or the default set). For example:</p>

  <pre>.../foo.git#v*,-v1.*  - exclude v1.* from v*
.../foo.git##-v1.*    - exclude v1.* from default set</pre>

  <p>To support specifying literal leading minus, a
  <code><i>refname</i></code> that starts with plus (<code><b>+</b></code>) is
  treated as an inclusion filter. For example:</p>

  <pre>.../foo.git#+x   - include  x
.../foo.git#+-x  - include -x
.../foo.git#++x  - include +x</pre>

  <p>Currently supported <code><b>git</b></code> protocols are
  <code><b>git://</b></code>, <code><b>ssh://</b></code> (but not
  <code>scp</code> pseudo-URL syntax), <code><b>http://</b></code>, and
  <code><b>https://</b></code> for remote repositories and
  <code><b>file://</b></code> for local repositories. While
  <code><b>bpkg</b></code> tries to minimize the amount of information
  (history) fetched, it is not always possible for some protocols and/or
  server configurations, as discussed next.</p>

  <p>A <code><b>git</b></code> repository accessible via
  <code><b>http(s)://</b></code> can use either <i>dumb</i> or <i>smart</i>
  protocol (refer to the <code><b>git</b></code> documentation for details).
  The dumb protocol provides only limited support for fetch minimization and
  if this protocol is used, then <code><b>bpkg</b></code> has no choice but to
  download a substantial amount of history.</p>

  <p>The smart protocol allows fetching of minimal history for tags and
  branches. Whether this is also possible for (all) commit ids depends on
  whether the server is configured to allow fetching unadvertised commits. For
  details, refer to the
  <code><b>uploadpack.allowReachableSHA1InWant</b></code> and
  <code><b>uploadpack.allowAnySHA1InWant</b></code> <code><b>git</b></code>
  configuration values.</p>

  <p>The <code><b>git://</b></code> and <code><b>ssh://</b></code> protocols
  are similar to smart <code><b>http://</b></code> in that they support
  fetching minimal history for tags and branches and may or may not support
  this for commit ids depending on the server configuration. Note, however,
  that unlike for <code><b>http(s)://</b></code>, for these protocols
  <code><b>bpkg</b></code> does not try to sense if fetching unadvertised
  commits is allowed and always assumes that it is not. Also note that the
  sensed or assumed protocol capabilities can be overridden for a
  <code><b>git</b></code> repository URL prefix using the
  <code><b>--git-capabilities</b></code> option (<a
  href="bpkg-common-options.xhtml"><code><b>bpkg-common-options(1)</b></code></a>).</p>

  <p>Based on this information, to achieve optimal results the recommended
  protocol for remote repositories is smart <code><b>https://</b></code>.
  Additionally, if you are planning to refer to unadvertised commit ids, then
  also consider configuring the server to allow fetching unadvertised
  commits.</p>

  <p>The <code><b>file://</b></code> protocol has the same fetch minimization
  support as <code><b>git://</b></code> and is therefore treated the same.</p>

  <h1>BUGS</h1>

  <p>Send bug reports to the
  <a href="mailto:users@build2.org">users@build2.org</a> mailing list.</p>

</div>

<div id="footer">
Copyright &#169; 2014-2024 the build2 authors.<br/>
Permission is granted to copy, distribute and/or modify this document under
the terms of the MIT License.
</div>

</body>
</html>
